#ifndef SEARCHER_H_
#define SEARCHER_H_

#include <assert.h>

#include "utils.h"
#include "segment.h"
#include "hash_table.h"
#include "index_cache.h"
#include "index_compressor.h"
#include "weight.h"


using namespace std;

struct SRes {
  int id;
  float score;
  string title;
  string url;
};


class Searcher {
public:
  Searcher();
  ~Searcher();

  /** search the query.
   *  
   *  @param  query        the query input by users.
   *  @param  show_num     how many results should be shown.
   *  @param  show_result  the result.
   *  @return the number of all related result.
   */
  int search(const string& query, const int show_num, SRes* show_result);
  
private:

  /** load the offset of inverted index from disk
   *
   *  @param  idx_file      the index file.
   *  @param  offset_list   the offset list
   */
  int load_offset_list(const string& idx_file, int*& offset_list);

  /** get the posting of a word
   *  the posting consists of the document id, document frequence
   *
   *  @param  idx_cache     the cache which cache the posting of one word
   *  @param  idx_file      the index file
   *  @param  offset_list   the offset list which is loaded by the function: load_offset_list
   *  @param  id            the word id
   *  @param  encode_list   the encode list of a word, which means the posting.
   */
  int get_posting(IndexCache* idx_cache,
                 const string& idx_file,
                 int* offset_list,
                 int id,
                 char* &encode_list);

  /** merge list
   */
  int merge_list(char* encode_list, int len, vector<int>& result);

  /** load document information
   *  include file length, url, etc.
   *
   *  @param file   the file that stored all document information.
   */
  int load_doc_info(const string& file);

  /** load words information
   *  include words, words id and document freqency.
   *
   *  @param file  the file that stored all words information.
   */
  int load_word_info(const string& file);

  /** get a specified word's information
   *
   *  @param  word   the word
   *  @return  a pair entry. the first is the word id, and second is the document freqency.
   */
  pair<int,int> get_info(const string& word);
  
private:
  
  HashTable* words_ht_;
  DocInfo* doc_info_;
  map<string,pair<int,int> > word_info_;
  IndexCache* cidx_cache_;
  IndexCache* tidx_cache_;
  IndexCompressor* index_compr_;

  Weight* weight_;
  string cidx_file_;
  string tidx_file_;
  int* coffset_list_;
  int* toffset_list_;
  int offset_size_;
  int total_doc_len_;
  int doc_num_;
  Segment* seg_;
};

#endif
